package com.common.spider.spideryf;

import com.common.spider.spideryf.entity.GoodsInfoEntity;
import com.common.spider.spideryf.enums.GoodsCategoryEnum;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;

/**
 * 使用http和Jsoup爬取益丰商城数据
 */
public class JsoupYfTest {

    /**
     * 商品编号初始设定
     */
    private static Integer intGoodsCode = 100001;

    public static void main(String[] args) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse httpResponse = null;
        String parentUrl = "http://www.yfdyf.com/product-";
        String childUrl = ".html";
        for (int i = 101; i < 9500; i++) {
            Integer page = i;
            String pages = page.toString();
            HttpGet request = new HttpGet(parentUrl + pages + childUrl);
            System.out.println("url:" + parentUrl + pages + childUrl);
            try {
                httpResponse = httpClient.execute(request);
                //状态不为200 抛出访问的异常信息
                if (HttpStatus.SC_OK == httpResponse.getStatusLine().getStatusCode()) {
                    HttpEntity httpEntity = httpResponse.getEntity();
                    //拿到页面源码
                    String html = EntityUtils.toString(httpEntity, "utf-8");
                    //解析html
                    parseHtml(html);
                } else {
                    System.out.println("返回状态不是200");
                    System.out.println(EntityUtils.toString(httpResponse.getEntity(), "utf-8"));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
//            finally {
//                //6.关闭
//                HttpClientUtils.closeQuietly(httpResponse);
//                HttpClientUtils.closeQuietly(httpClient);
//            }
        }
        System.out.println("--------数据爬取完成-------");
    }

    /**
     * 解析html
     */
    public static void parseHtml(String html) {
        //装载 需要收集的数据 容器
        GoodsInfoEntity goodsInfoEntity = new GoodsInfoEntity();
        //是否有商品名称判断 -- true为有
        Boolean haveNames = true;
        //是否为处方药 -- true为不是
        Boolean isntPrescription = true;

        //商品价格
        BigDecimal price = null;
        //商品图片集合
        //缩略图
        String goodsPictures = "";
        //高清图
        String goodsJpgs = "";
        //jsoup读取html源码字符串
        Document document = Jsoup.parse(html);
        //System.out.println(html);
        //解析1 拿到商品名称有关标签内容
        Elements name = document.select("div[class=mainhead]").select("h2[class=main-tit]");
        //解析2 拿到商品分类有关标签内容
        Elements category = document.select("div[class=subnav-position]").select("a");
        //解析3 拿到商品价格有关
        Elements htmlprice = document.select("strong[class=goodsprice]");
        //解析4 拿到商品的详细信息
        Elements goodinfos = document.select("ul[class=pro-instruction]").select("li");
        //解析5 拿到商品主图片url元素
        Elements pictures1 = document.select("a[class=list2_small_current]");
        //解析6 拿到商品从图片url元素
        Elements pictures2 = document.select("a[class=list2_pro_small]");


        if (goodinfos.isEmpty()) {
            return;
        }
        //解析商品详细信息
        for (Element element : goodinfos) {
            String infoItem = element.text();
            System.out.println(infoItem);
            //处方药直接跳过此商品
            if (infoItem.contains("处 方 药") || infoItem == null) {
                if (infoItem.contains("是")) {
                    System.out.println("==============");
                    isntPrescription = false;
                    return;
                }

            } else if (infoItem.contains("剂 型")) {
                String[] doForm = infoItem.split("剂 型：");
                if (doForm.length > 1) {
                    goodsInfoEntity.setDosageForm(doForm[1]);
                    System.out.println("剂型：" + doForm[1]);
                }

            } else if (infoItem.contains("剂型")) {
                String[] doaForm = infoItem.split("剂型：");
                if (doaForm.length > 1) {
                    goodsInfoEntity.setDosageForm(doaForm[1]);
                    System.out.println("剂型：" + doaForm[1]);
                }

            } else if (infoItem.contains("批准文号")) {
                String[] alyNumber = infoItem.split("批准文号：");
                if (alyNumber.length > 1) {
                    goodsInfoEntity.setAuNo(alyNumber[1]);
                    System.out.println("批准文号：" + alyNumber[1]);
                }

            } else if (infoItem.contains("注册证编号")) {
                String[] regNumber = infoItem.split("注册证编号：");
                if (regNumber.length > 1) {
                    goodsInfoEntity.setAuNo(regNumber[1]);
                    System.out.println("注册证编号：" + regNumber[1]);
                }
            } else if (infoItem.contains("生产厂家")) {
                String[] procom = infoItem.split("生产厂家：");
                if (procom.length > 1) {
                    goodsInfoEntity.setCompany(procom[1]);
                    System.out.println("生产厂家：" + procom[1]);
                }
            } else if (infoItem.contains("规 格")) {
                String[] specifica = infoItem.split("规 格：");
                if (specifica.length > 1) {
                    goodsInfoEntity.setSpecification(specifica[1]);
                    System.out.println("规格：" + specifica[1]);
                }

            } else if (infoItem.contains("规格")) {
                String[] spcifica = infoItem.split("规格：");
                if (spcifica.length > 1) {
                    goodsInfoEntity.setSpecification(spcifica[1]);
                    System.out.println("规格：" + spcifica[1]);
                }
            }
        }

        //商品名称名称
        if (name.isEmpty() || !isntPrescription) {
            haveNames = false;
        } else {
            for (Element element : name) {
                String nameData = element.text();
                goodsInfoEntity.setGoodsName(nameData);
                System.out.println(nameData);
            }
        }

        if (haveNames && isntPrescription) {
            //http://www.yfdyf.com/product-2501.html 没有商品
            //拿到分类
            if (!category.isEmpty()) {
                Element ce = category.get(1);
                String cateName = ce.text();
                //匹配分类code
                String cateCode = selectCategory(cateName);
                goodsInfoEntity.setCategoryCode(cateCode);
                System.out.println("商品分类code:" + cateCode + ";name:" + cateName);
            }
            //取出价格 过滤标签属性
            if (htmlprice.isEmpty()) {
                return;
            }
            for (Element element : htmlprice) {
                String goodprice = element.text();
                System.out.println("分割前的price：" + goodprice);
                //将商品价格不唯一的 全部取最低价
                if (goodprice.contains("-")) {
                    System.out.println("该商品价格不唯一");
                    String[] array = goodprice.split("-");
                    Double pdouble = Double.valueOf(array[0]);
                    //toString()避免精度坑
                    price = new BigDecimal(pdouble.toString());
                    goodsInfoEntity.setGoodsPrice(price);
                    System.out.println(price);
                } else {
                    Double pdouble = Double.valueOf(goodprice);
                    //toString()避免精度坑
                    price = new BigDecimal(pdouble.toString());
                    goodsInfoEntity.setGoodsPrice(price);
                    System.out.println(price);
                }
            }

            //拿到图片
            //主图
            if (!pictures1.isEmpty()) {
                Element eMainJpg = pictures1.get(0);
                String mJpgSrc = eMainJpg.attr("imginfo");
                //前面作缩略，后面的作高清
                String newJpgSrc = mJpgSrc.replace("{small:'", "").replace
                        ("',big:'", ",").replace("'}", "");
                goodsInfoEntity.setGoodsPicture(newJpgSrc);
                System.out.println("主图：" + newJpgSrc);
            }
            //从图
            System.out.println("图url:" + pictures2);
            //System.out.println("names:" + haveNames);

            for (Element element : pictures2) {

                String label = element.attr("imginfo");
                String model = label.replace("{small:'", "").replace
                        ("',big:'", ",").replace("'}", "");

                //单个图片中的 缩略图和高清图
                String pgList[] = model.split(",");
                //单张图片必须有两种格式才进行保存
                if (pgList.length > 1) {
                    //缩略图
                    goodsPictures = goodsPictures + pgList[0] + ",";
                    //高清图
                    goodsJpgs = goodsJpgs + pgList[1] + ",";
                    System.out.println("model:" + model);
                    //缩略图
                    System.out.println("pic:" + pgList[0]);
                    //高清图
                    System.out.println("jpg:" + pgList[1]);
                }
            }
            //缩略图
            goodsInfoEntity.setGoodsPictures(goodsPictures);
            //高清图
            goodsInfoEntity.setGoodsJpgs(goodsJpgs);
            System.out.println(goodsPictures);
            System.out.println(goodsPictures.split(",")[0]);

            goodsInfoEntity.setGoodsCode(intGoodsCode.toString());
            System.out.println("goodsCode:" + intGoodsCode);
            //id
            int id = intGoodsCode;
//            goodsInfoEntity.setId(id);
            intGoodsCode++;

            try {
                openSqlSession(goodsInfoEntity);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * sql会话 用于sql的事务操作。传入所需的实体
     */
    public static void openSqlSession(GoodsInfoEntity goodsInfoEntity) throws IOException {
        String resource = "Mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession();
        int result = session.insert("insertGood", goodsInfoEntity);
        System.out.println("result:" + result);

        //提交事务
        session.commit();
        session.close();
    }

    /**
     * 传入分类名，筛选出商品分类的code
     */
    public static String selectCategory(String name) {
        for (GoodsCategoryEnum gce : GoodsCategoryEnum.values()) {
            if (gce.getName().equals(name)) {
                return gce.getCode();
            }
        }
        //如果枚举类中欧没有找到对应code，返回“其他”
        return "12";
    }
}
